package com.xbts.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huaweicloud.sdk.core.auth.GlobalCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.osm.v2.OsmClient;
import com.huaweicloud.sdk.osm.v2.model.*;
import com.huaweicloud.sdk.osm.v2.region.OsmRegion;
import com.xbts.common.constant.Constants;
import com.xbts.common.core.domain.AjaxResult;
import com.xbts.common.core.domain.entity.SysUser;
import com.xbts.common.core.redis.RedisCache;
import com.xbts.common.enums.SettingEnum;
import com.xbts.common.exception.ServiceException;
import com.xbts.common.utils.SecurityUtils;
import com.xbts.common.utils.StringUtils;
import com.xbts.system.domain.CnUserCases;
import com.xbts.system.domain.dto.AccountSetting;
import com.xbts.system.module.sms.HttpUtils;
import com.xbts.system.service.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author llk
 * @Date 2023/8/9 14:27
 */
@Service
@Slf4j
public class CloudCasesServiceImpl implements ICloudCasesService {

    @Autowired
    private SettingService settingService;
    @Autowired
    private ICnRegionService cnRegionService;
    @Autowired
    private ICnUserCasesService cnUserCasesService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ICloudServiceService cloudServiceService;

    @Override
    public ListProblemTypesResponse listProblemTypes(ListProblemTypesRequest listProblemTypesRequest) {
        if (StringUtils.isEmpty(listProblemTypesRequest.getProductCategoryId())
                || listProblemTypesRequest.getProductCategoryId().equals(defaultProductCategoryId)) {
            ListProblemTypesResponse response = redisCache.getCacheObject(Constants.LIST_PROBLEM_TYPES_KEY);
            if (null != response) {
                return response;
            }
        }
        OsmClient client = getOsmClient();
        ListProblemTypesResponse response = null;
        try {
            if (StringUtils.isEmpty(listProblemTypesRequest.getProductCategoryId())) {
                listProblemTypesRequest.setProductCategoryId(defaultProductCategoryId);
            }
            response = client.listProblemTypes(listProblemTypesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("获取问题类型列表失败", e);
        }
        if (response != null) {
            redisCache.setCacheObject(Constants.LIST_PROBLEM_TYPES_KEY, response, 15, TimeUnit.MINUTES); // 15 分钟
        }
        return response;
    }

    // status：状态 0：待受理(已派发) 1：处理中 2：待确认结果 3：已完成 4：已撤销 12：无效 17： 待反馈
    @Override
    public AjaxResult listCases(ListCasesRequest listCasesRequest) {
        OsmClient client = getOsmClient();

        ListCasesResponse response = null;
        try {
            response = client.listCases(listCasesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("获取工单列表失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("获取工单列表失败");
    }

    @Override
    public AjaxResult createCases(CreateCasesRequest createCasesRequest) {
        AccountSetting accountSetting = settingService.getAccountSetting(SettingEnum.HUAWEI);
        // 长度超过 1200 会报错
        if (createCasesRequest.getBody().getSimpleDescription().length() > 1200)
            return AjaxResult.error("工单描述长度不能超过 1200");
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        String regionId = createCasesRequest.getBody().getRegionId();
        regionId = StringUtils.isEmpty(regionId) ? accountSetting.getRegionId() : regionId;

        OsmClient client = getOsmClient();

        CreateOrderIncidentV2Req body = createCasesRequest.getBody();
        body.setSourceId("83aeb0f2834c4df49826c781d32a963e"); // 固定值
        body.setRegionId(regionId);
        body.setProjectId(cnRegionService.selectCnRegionByRegionId(regionId).getProjectId());
        if (StringUtils.isEmpty(sysUser.getPhonenumber())) {
            return AjaxResult.error("请先绑定手机号");
        }

        String xPhoneVerifiedId = getXPhoneVerifiedId(sysUser.getPhonenumber());
        if (StringUtils.isEmpty(xPhoneVerifiedId)) {
            return AjaxResult.error("请先验证手机号");
        }
        body.setRemindMobile(sysUser.getPhonenumber());
        createCasesRequest.setXPhoneVerifiedid(xPhoneVerifiedId);

        CreateCasesResponse response = null;
        try {
            response = client.createCases(createCasesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("创建工单失败", e);
        }
        if (response != null && response.getIncidentId() != null) {
            // 保存用户与工单的关系
            CnUserCases cnUserCases = new CnUserCases();
            cnUserCases.setStatus("0");
            cnUserCases.setIncidentId(response.getIncidentId());
            cnUserCases.setSimpleDescription(body.getSimpleDescription());
            ListProblemTypesResponse listProblemTypesResponse = this.listProblemTypes(new ListProblemTypesRequest());
            if (listProblemTypesResponse != null) {
                List<SimpleIncidentBusinessTypeV2> incidentBusinessTypeList = listProblemTypesResponse.getIncidentBusinessTypeList();
                for (SimpleIncidentBusinessTypeV2 simpleIncidentBusinessTypeV2 : incidentBusinessTypeList) {
                    if (simpleIncidentBusinessTypeV2.getBusinessTypeId().equals(body.getBusinessTypeId())) {
                        cnUserCases.setBusinessTypeId(simpleIncidentBusinessTypeV2.getBusinessTypeId());
                        cnUserCases.setBusinessTypeName(simpleIncidentBusinessTypeV2.getBusinessTypeName());
                        cnUserCases.setCaseType(simpleIncidentBusinessTypeV2.getCaseType());
                        break;
                    }
                }
            }
            cnUserCasesService.insertCnUserCases(cnUserCases);
            return AjaxResult.success(response);
        } else
            return AjaxResult.error("创建工单失败");
    }

    @Override
    public AjaxResult listCustomersRegions() {
        OsmClient client = getOsmClient();
        ListCustomersRegionsRequest request = new ListCustomersRegionsRequest();
        ListCustomersRegionsResponse response = null;
        try {
            response = client.listCustomersRegions(request);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("获取区域列表失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("获取区域列表失败");
    }

    @Override
    public AjaxResult showCaseDetail(ShowCaseDetailRequest showCaseDetailRequest) {
        OsmClient client = getOsmClient();
        ShowCaseDetailResponse response = null;
        try {
            response = client.showCaseDetail(showCaseDetailRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("获取工单详情失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("获取工单详情失败");
    }

    @Override
    public AjaxResult uploadJsonAccessories(MultipartFile file) {
        OsmClient client = getOsmClient();
        UploadJsonAccessoriesResponse response = null;
        try {
            String base64Str = Base64.getEncoder().encodeToString(file.getBytes());
            UploadJsonAccessoriesRequest uploadJsonAccessoriesRequest = new UploadJsonAccessoriesRequest();
            AccessoryJsonFormatReq body = new AccessoryJsonFormatReq();
            body.setAccessoryData(base64Str);
            body.setAccessoryFrom("incident");// 固定值
            body.setAccessoryName(file.getOriginalFilename());
            body.setUploadType(1);
            uploadJsonAccessoriesRequest.withBody(body);
            response = client.uploadJsonAccessories(uploadJsonAccessoriesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException | IOException e) {
            log.error("上传附件失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("上传附件失败");
    }

    @Override
    public AjaxResult createScores(CreateScoresRequest createScoresRequest) {
        OsmClient client = getOsmClient();
        CreateScoresRequest request = new CreateScoresRequest();
        CreateScoreV2Req body = new CreateScoreV2Req();
        request.withBody(body);
        CreateScoresResponse response = null;
        try {
            response = client.createScores(request);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("评价失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("评价失败");
    }

    @Override
    public AjaxResult updateNewInstantMessagesRead(UpdateNewInstantMessagesReadRequest updateNewInstantMessagesReadRequest) {
        OsmClient client = getOsmClient();
        UpdateNewInstantMessagesReadRequest request = new UpdateNewInstantMessagesReadRequest();
        UpdateUnreadNewInstantMsgV2Req body = new UpdateUnreadNewInstantMsgV2Req();
        request.withBody(body);
        UpdateNewInstantMessagesReadResponse response = null;
        try {
            response = client.updateNewInstantMessagesRead(request);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("更新消息失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("更新消息失败");
    }

    @Override
    public AjaxResult listUnreadNewInstantMessages(ListUnreadNewInstantMessagesRequest listUnreadNewInstantMessagesRequest) {
        OsmClient client = getOsmClient();
        ListUnreadNewInstantMessagesResponse response = null;
        try {
            response = client.listUnreadNewInstantMessages(listUnreadNewInstantMessagesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("获取消息列表失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("获取消息列表失败");
    }

    @Override
    public AjaxResult createMessages(CreateMessagesRequest createMessagesRequest) {
        OsmClient client = getOsmClient();
        CreateMessagesResponse response = null;
        try {
            response = client.createMessages(createMessagesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("提交留言失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("提交留言失败");
    }

    @Override
    public AjaxResult revokeMessage(RevokeMessageRequest revokeMessageRequest) {
        OsmClient client = getOsmClient();
        RevokeMessageResponse response = null;
        try {
            response = client.revokeMessage(revokeMessageRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("撤回留言失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("撤回留言失败");
    }

    @Override
    public AjaxResult listMessages(ListMessagesRequest listMessagesRequest) {
        OsmClient client = getOsmClient();
        ListMessagesResponse response = null;
        try {
            response = client.listMessages(listMessagesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("查询留言失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("查询留言失败");
    }

    @Override
    public AjaxResult listMoreInstantMessages(ListMoreInstantMessagesRequest listMoreInstantMessagesRequest) {
        OsmClient client = getOsmClient();
        ListMoreInstantMessagesResponse response = null;
        try {
            response = client.listMoreInstantMessages(listMoreInstantMessagesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("查询更多留言失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("查询更多留言失败");
    }

    @Override
    public AjaxResult listNewInstantMessages(ListNewInstantMessagesRequest listNewInstantMessagesRequest) {
        OsmClient client = getOsmClient();
        ListNewInstantMessagesResponse response = null;
        try {
            response = client.listNewInstantMessages(listNewInstantMessagesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("轮询查询即时消息失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("轮询查询即时消息失败");
    }

    @Override
    public AjaxResult sendVerifyCodes(SendVerifyCodesRequest sendVerifyCodesRequest) {
        OsmClient client = getOsmClient();
        SendVerifyCodesResponse response = null;
        try {
            response = client.sendVerifyCodes(sendVerifyCodesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("发送验证码失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("发送验证码失败");
    }

    @Override
    public ListHasVerifiedContactsResponse listHasVerifiedContacts(ListHasVerifiedContactsRequest listHasVerifiedContactsRequest) {
        OsmClient client = getOsmClient();
        ListHasVerifiedContactsResponse response = null;
        try {
            response = client.listHasVerifiedContacts(listHasVerifiedContactsRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("查询已验证联系人失败", e);
        }
        return response;
    }

    @Override
    public AjaxResult checkVerifyCodes(CheckVerifyCodesRequest checkVerifyCodesRequest) {
        OsmClient client = getOsmClient();
        CheckVerifyCodesResponse response = null;
        try {
            response = client.checkVerifyCodes(checkVerifyCodesRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("校验验证码失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("校验验证码失败");
    }

    @Override
    public CheckNeedVerifyResponse checkNeedVerify(CheckNeedVerifyRequest checkNeedVerifyRequest) {
        OsmClient client = getOsmClient();
        // 默认手机号联系方式
        if (null == checkNeedVerifyRequest.getContactWay()) {
            checkNeedVerifyRequest.withContactWay(0);
        }
        CheckNeedVerifyResponse response = null;
        try {
            response = client.checkNeedVerify(checkNeedVerifyRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("校验是否需要验证码失败", e);
        }
        return response;
    }

    @Override
    public AjaxResult deleteAccessories(DeleteAccessoriesRequest deleteAccessoriesRequest) {
        OsmClient client = getOsmClient();
        DeleteAccessoriesResponse response = null;
        try {
            response = client.deleteAccessories(deleteAccessoriesRequest);
            System.out.println(response.toString());
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("删除附件失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("删除附件失败");
    }

    @Override
    public void downloadAccessories(DownloadAccessoriesRequest downloadAccessoriesRequest, HttpServletResponse httpServletResponse) {
//        OsmClient client = getOsmClient();
//        DownloadAccessoriesResponse response = null;
//        try {
//            response = client.downloadAccessories(downloadAccessoriesRequest);
//            System.out.println(response.toString());
//        } catch (ConnectionException | RequestTimeoutException e) {
//            e.printStackTrace();
//        } catch (ServiceResponseException e) {
//            log.error("下载附件失败", e);
//        }
//        if (response != null)
//            return AjaxResult.success("操作成功", JSONObject.toJSONString(response));
//        else
//            return AjaxResult.error("下载附件失败");
        String url = String.format("https://osm.cn-south-1.myhuaweicloud.cn/v2/servicerequest/accessorys/%s"
                , downloadAccessoriesRequest.getAccessoryId());
        Response response = HttpUtils.sendHuaWeiCloudByGet(url, cloudServiceService.keystoneCreateUserTokenByPassword());
        try {
            assert response.body() != null;
            InputStream inputStream = response.body().byteStream();
            // 判断InputStream是否为空
            if (inputStream.available() == 0) {
                log.error("文件不存在: {}", downloadAccessoriesRequest.getAccessoryId());
                return;
            }
            httpServletResponse.setContentType("application/octet-stream");
            httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + downloadAccessoriesRequest.getAccessoryId());
            IOUtils.copy(inputStream, httpServletResponse.getOutputStream());
            httpServletResponse.flushBuffer();
        } catch (IOException e) {
            log.error("下载附件失败", e);
        }
    }

    @Override
    public void downloadImages(DownloadImagesRequest downloadImagesRequest, HttpServletResponse httpServletResponse) {
//        OsmClient client = getOsmClient();
//        DownloadImagesResponse response = null;
//        try {
//            response = client.downloadImages(downloadImagesRequest);
//            System.out.println("response.toString(): " + response.toString());
//        } catch (ConnectionException | RequestTimeoutException e) {
//            e.printStackTrace();
//        } catch (ServiceResponseException e) {
//            log.error("图片展示失败", e);
//        }
//        if (response != null) {
//            return AjaxResult.success("操作成功", JSONObject.toJSONString(response));
//        } else
//            return AjaxResult.error("图片展示失败");
        String url = String.format("https://osm.cn-south-1.myhuaweicloud.cn/v2/servicerequest/accessorys/%s/image"
                , downloadImagesRequest.getAccessoryId());
        Response response = HttpUtils.sendHuaWeiCloudByGet(url, cloudServiceService.keystoneCreateUserTokenByPassword());
        assert response.body() != null;
        InputStream inputStream = response.body().byteStream();
        try {
            // 判断InputStream是否为空
            if (inputStream.available() == 0) {
                log.error("文件不存在: {}", downloadImagesRequest.getAccessoryId());
                return;
            }
            httpServletResponse.setContentType("application/octet-stream");
            httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + downloadImagesRequest.getAccessoryId());

            FileOutputStream fileOutputStream = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\test.png"));
            IOUtils.copy(inputStream, fileOutputStream);
            IOUtils.copy(inputStream, httpServletResponse.getOutputStream());
            httpServletResponse.flushBuffer();
        } catch (IOException e) {
            log.error("下载附件失败", e);
        }
    }

    @Override
    public AjaxResult showAccessoryLimits(ShowAccessoryLimitsRequest showAccessoryLimitsRequest) {
        OsmClient client = getOsmClient();
        ShowAccessoryLimitsResponse response = null;
        try {
            response = client.showAccessoryLimits(showAccessoryLimitsRequest);
        } catch (ConnectionException | RequestTimeoutException e) {
            e.printStackTrace();
        } catch (ServiceResponseException e) {
            log.error("查询附件限制失败", e);
        }
        if (response != null)
            return AjaxResult.success(response);
        else
            return AjaxResult.error("查询附件限制失败");

    }

    @Override
    public List<CnUserCases> sysListCases(CnUserCases cnUserCases) {
        if (SecurityUtils.getUserId() == null) {
            throw new ServiceException("用户未登录!");
        }
        QueryWrapper<CnUserCases> queryWrapper = cnUserCases.queryWrapper();
        queryWrapper.eq("user_id", SecurityUtils.getUserId());
        List<CnUserCases> list = cnUserCasesService.list(queryWrapper);
        // 查询工单状态
        for (CnUserCases userCases : list) {
            Integer status = this.showCaseStatus(new ShowCaseStatusRequest().withCaseId(userCases.getIncidentId()));
            if (status != null) {
                userCases.setStatus(String.valueOf(status));
            }
        }
        // 过滤状态
        if (list.size() > 0) {
            if (StringUtils.isNotEmpty(cnUserCases.getStatus())){
                list = list.stream().filter(item -> cnUserCases.getStatus().equals(item.getStatus())).collect(Collectors.toList());
            }
        }
        return list;
    }

    @Override
    public Integer showCaseStatus(ShowCaseStatusRequest showCaseStatusRequest) {
        OsmClient client = getOsmClient();
        try {
            ShowCaseStatusResponse response = client.showCaseStatus(showCaseStatusRequest);
            return response.getStatus();
        } catch (Exception e) {
           log.error("查询工单状态失败", e);
           return null;
        }
    }

    /**
     * 获取XphoneVerifiedid
     *
     * @param phoneNUmber 电话号码
     * @return
     */
    private String getXPhoneVerifiedId(String phoneNUmber) {
        CheckNeedVerifyRequest checkNeedVerifyRequest = new CheckNeedVerifyRequest();
        checkNeedVerifyRequest.withContactWay(0);
        checkNeedVerifyRequest.withContactValue(phoneNUmber);
        CheckNeedVerifyResponse checkNeedVerifyResponse = this.checkNeedVerify(checkNeedVerifyRequest);
        if (null != checkNeedVerifyResponse) {
            Integer needVerifyCode = checkNeedVerifyResponse.getNeedVerifyCode();
            // 已经验证过的手机号
            if (needVerifyCode == 0) {
                // 获取XphoneVerifiedid
                ListHasVerifiedContactsRequest listHasVerifiedContactsRequest = new ListHasVerifiedContactsRequest();
                listHasVerifiedContactsRequest.withContactWay(0);
                ListHasVerifiedContactsResponse listHasVerifiedContactsResponse = this.listHasVerifiedContacts(listHasVerifiedContactsRequest);
                if (null != listHasVerifiedContactsResponse) {
                    return listHasVerifiedContactsResponse.getContactList().get(0).getVerifiedId();
                }
            } else {
                return null;
            }
        }
        return null;
    }

    /**
     * 获取OsmClient
     *
     * @return OsmClient
     */
    private OsmClient getOsmClient() {
        AccountSetting accountSetting = settingService.getAccountSetting(SettingEnum.HUAWEI);
        ICredential auth = new GlobalCredentials()
                .withAk(accountSetting.getAccessKeyId())
                .withSk(accountSetting.getSecretAccessKey());

        return OsmClient.newBuilder()
                .withCredential(auth)
                .withRegion(OsmRegion.valueOf("cn-south-1"))
                .build();
    }
}
